package com.young.ysepay.service.impl;

import com.alibaba.fastjson.JSON;
import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils;
import com.young.ysepay.constants.RefundConstants;
import com.young.ysepay.dao.YsRefundDao;
import com.young.ysepay.dao.YsRefundReceiptDao;
import com.young.ysepay.dao.YsRefundRequestparamDao;
import com.young.ysepay.domain.SysconfigYsRefundReceiptDO;
import com.young.ysepay.domain.YsRefundRequestparamDO;
import com.young.ysepay.dto.YsPayDTO;
import com.young.ysepay.service.YsBuildRequestParaService;
import com.young.ysepay.service.YsBusinessPramService;
import com.young.ysepay.service.YsRefundService;
import com.young.ysepay.service.YsVerifyJsonSignService;
import com.young.ysepay.utils.DateFormatHelper;
import com.young.ysepay.utils.Https;
import com.young.ysepay.utils.JSONUtils;
import com.young.ysepay.utils.apiresult.ApiResult;
import com.young.ysepay.utils.apiresult.ApiResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * describe:
 *
 * @author zhaopengjun
 * @date 2019/6/4 18:17
 */
@Service
public class YsRefundServiceImpl implements YsRefundService {
    public static final Logger logger = LoggerFactory.getLogger(YsRefundServiceImpl.class);

    @Autowired
    private YsRefundService ysRefundService;

    @Autowired
    private YsBusinessPramService ysBusinessPramService;

    @Autowired
    YsBuildRequestParaService ysBuildRequestParaService;

    @Autowired
    YsVerifyJsonSignService ysVerifyJsonSignService;

  /*  @Autowired
    YsRefundDao ysRefundDao;
*/
    @Autowired
    YsRefundRequestparamDao ysRefundDao;
    @Autowired
    YsRefundReceiptDao ysRefundReceiptDao;

    @Transactional(rollbackFor = Exception.class)
    public String ysRoutingRefundRequest(Map<String, Object> paraMap) {
        logger.info("————————————请求参数——————————————————————————"+JSON.toJSONString(paraMap));
        //校验参数
        Boolean bo = verifyRoutingRefund(paraMap);
        if (!bo) {
            logger.info("YsRefundServiceImpl-->ysRoutingRefundRequest params:" + JSON.toJSONString(paraMap));
            return String.valueOf(ApiResult.failure("请求参数为空!"));
        }
        //请求参数保存
        Map<String, Object> map = null;
        int sum =0;
        try {
            Boolean b = saveParam(paraMap);
            if (!b) {
                logger.error("YsRefundServiceImpl-->saveParam 请求参数数据保存失败!");
                return String.valueOf(ApiResult.failure("请求参数为空!"));
            }
            //拼接业务参数并获取银盛接口：
            map = routingJointVerifyParam(paraMap);
            SysconfigYsRefundReceiptDO ysRefundReceiptDO = new SysconfigYsRefundReceiptDO();
            //获取返回结果集
            if (null != map && map.get("code").equals("10000")) {
                String refundAmount = (String) map.get("refund_amount");
                String tradeNo = (String) map.get("trade_no");
                String outTradeNo = (String) map.get("out_trade_no");
                String accountDate = (String) map.get("account_date");
                ysRefundReceiptDO.setRefundAmount(new BigDecimal(refundAmount));
                ysRefundReceiptDO.setTradeNo(tradeNo);
                ysRefundReceiptDO.setOutTradeNo(outTradeNo);
                ysRefundReceiptDO.setAccountDate(accountDate);
                ysRefundReceiptDO.setGmtCreate(new Date());
                ysRefundReceiptDO.setIsDelete(RefundConstants.COMMON_FLAG_UNDEL);
                ysRefundReceiptDO.setRefundType(RefundConstants.ROUTING_REFUND);
                sum = ysRefundDao.saveRoutingReceipt(ysRefundReceiptDO);
                logger.error("YsRefundServiceImpl------------saveReceipt 保存數據條數" + sum);
            }
        } catch (Exception e) {
            logger.error("YsRefundServiceImpl-->ysRoutingRefundRequest fail e:", e.toString());
            //TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            ApiResult.failure(ApiResultCode.FAILURE, "");
        } finally {
            if(sum>0){
                return "SUCCESS";
            }else {
                return "FALL";
            }

        }
    }

    //普通退款請求參數校驗
    public Boolean verifyRefund(Map<String, Object> paraMap) {
        String refundAmount = (String) paraMap.get("refund_amount");
        String refundReason = (String) paraMap.get("refund_reason");
        String outRequestNo = (String) paraMap.get("out_request_no");
        if (paraMap.isEmpty()) {
            return false;
        }
        if (StringUtils.isEmpty(refundAmount)) {
            logger.info("YsRefundServiceImpl-->verifyRefund params 退款金额为" + refundAmount);
            return false;
        }
        if (StringUtils.isEmpty(refundReason)) {
            logger.info("YsRefundServiceImpl-->verifyRefund params 退款说明为" + refundReason);
            return false;
        }
        if (StringUtils.isEmpty(outRequestNo)) {
            logger.info("YsRefundServiceImpl-->verifyRefund params 退款请求标示为" + outRequestNo);
            return false;
        }
        return true;

    }

  /*  //普通退款請求參數
    public Boolean saveYsRefundRequest(Map<String, Object> paraMap) {
        String outTradeNo = (String) paraMap.get("out_trade_no");
        String tradeNo = (String) paraMap.get("trade_no");
        //需要退款金額
        String refundAmount = (String) paraMap.get("refund_amount");
        String refundReason = (String) paraMap.get("refund_reason");
        String outRequestNo = (String) paraMap.get("out_request_no");

        SysconfigYsRefundRequestparamDO sysparamDO = new SysconfigYsRefundRequestparamDO();
        sysparamDO.setOutTradeNo(outTradeNo);
        sysparamDO.setTradeNo(tradeNo);
        sysparamDO.setRefundAmount(new BigDecimal(refundAmount));
        sysparamDO.setRefundReason(refundReason);
        sysparamDO.setOutRequestNo(outRequestNo);
        sysparamDO.setGmtCreate(new Date());
        sysparamDO.setIsDelete(RefundConstants.COMMON_FLAG_UNDEL);
        sysparamDO.setRefundType(RefundConstants.REFUND);

        int saveSum = ysRefundDao.saveYsRefundRequest(sysparamDO);
        if (saveSum < 0) {
            logger.error("YsRefundServiceImpl-------------saveYsRefundRequest:普通退款请求参数记录条数" + saveSum);
            return false;
        }
        return true;
    }*/
/*
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String ysRefundRequest(Map<String, Object> paraMap) {
        //校驗參數
        Boolean b = verifyRefund(paraMap);
        if (!b) {
            logger.error("YsRefundServiceImpl-->ysRefundRequest params:" + JSON.toJSONString(paraMap));
            return String.valueOf(ApiResult.failure("请求参数为空!"));
        }
        Map<String, Object> refundmap = null;
        int sum = 0;
        try {
            //请求参数保存
            Boolean boo = saveYsRefundRequest(paraMap);
            if (!boo) {
                logger.error("YsRefundServiceImpl-->saveYsRefundRequest 请求参数数据保存失败!");
            }
            //封装业务参数并请求银盛
            refundmap = jointVerifyParam(paraMap);
            SysconfigYsRefundReceiptDO sysconfigYsRefundReceiptDO = new SysconfigYsRefundReceiptDO();
            //获取返回结果集
            if (null != refundmap && !refundmap.isEmpty()) {
                String refundAmount = (String) refundmap.get("refund_amount");
                String tradeNo = (String) refundmap.get("trade_no");
                String outTradeNo = (String) refundmap.get("out_trade_no");
                String accountDate = (String) refundmap.get("account_date");
                sysconfigYsRefundReceiptDO.setRefundAmount(new BigDecimal(refundAmount));
                sysconfigYsRefundReceiptDO.setTradeNo(tradeNo);
                sysconfigYsRefundReceiptDO.setOutTradeNo(outTradeNo);
                sysconfigYsRefundReceiptDO.setAccountDate(accountDate);
            }
            sysconfigYsRefundReceiptDO.setGmtCreate(new Date());
            sysconfigYsRefundReceiptDO.setIsDelete(RefundConstants.COMMON_FLAG_UNDEL);
            sysconfigYsRefundReceiptDO.setRefundType(RefundConstants.ROUTING_REFUND);
            sum = ysRefundDao.saveReceipt(sysconfigYsRefundReceiptDO);
            logger.info("YsRefundServiceImpl------------saveReceipt 保存數據條數" + sum);

        } catch (Exception e) {
            logger.error("YsRefundServiceImpl-->ysRefundRequest fail e:", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            ApiResult.failure(ApiResultCode.FAILURE, "");
        } finally {
            if(sum>0){
                return "SUCCESS";
            }else {
                return "FALL";
            }
        }

    }*/

    private Map<String, Object> jointVerifyParam(Map<String, Object> paraMap) throws Exception {

        Map<String, Object> resultMap = new HashMap<String, Object>();
        YsPayDTO ysPayDTO = ysBusinessPramService.ysBusinessPram();

        Map<String, Object> businessMap = new HashMap<>();
        businessMap.put("biz_content", JSON.toJSONString(paraMap));
        //公共参数
        Map<String, String> commonMap = new HashMap<>();
        commonMap.put("method", "ysepay.online.trade.refund");
        commonMap.put("partner_id", ysPayDTO.getPARTNER_ID());
        commonMap.put("timestamp", DateFormatHelper.getNowTimeStr());
        commonMap.put("charset", ysPayDTO.getDEFAULT_CHARSET());
        commonMap.put("sign_type", ysPayDTO.getSIGN_ALGORITHM());
        commonMap.put("version", ysPayDTO.getVERSION());
        commonMap.put("biz_content", JSON.toJSONString(businessMap));

        Map<String, String> sParaMap = ysBuildRequestParaService.buildRequestPara(commonMap);
        String returns = Https.httpsSend(ysPayDTO.getYSEPAY_GATEWAY_URL_DSF(), sParaMap);
        logger.error("银盛返回值"+resultMap);
        resultMap = (Map) JSON.parse(returns);
        Object obj = resultMap.get("ysepay_online_trade_refund_response");
        boolean verifyResult = false;
        if(obj != null){
            //Map<String, Object> ysepay_online_trade_refund_response = (Map) JSON.parseObject(obj.toString());
            int yscount = returns.toString().indexOf("ysepay_online_trade_refund_response");
            String str = returns.substring(yscount);
            str = str.replace("ysepay_online_trade_refund_response", "");
            str = str.substring(2, str.length() - 1);
            verifyResult = ysVerifyJsonSignService.verifyJsonSign(resultMap.get("sign").toString(), str, "utf-8");
            logger.info("YsRefundServiceImpl -------------------routingJointVerifyParam"+"校验是否成功"+verifyResult+resultMap);
            Map<String, Object> map = JSONUtils.jsonToMap(str);
            return map;
        }
        return null;
    }

    public String ysRefundQuery(Map<String, Object> paraMap) {
        logger.info("YsRefundServiceImpl-->ysRefundQuery params:" + JSON.toJSONString(paraMap));
        Map<String, Object> resultMap = new HashMap<String, Object>();
        String str = "";
        YsPayDTO ysPayDTO = ysBusinessPramService.ysBusinessPram();
        String outRequestNo = (String) paraMap.get("out_request_no");
        //判断参数为空值
        if (paraMap.isEmpty()) {
            logger.error("YsRefundServiceImpl --------------paraMap" + paraMap);
            return String.valueOf(ApiResult.failure(ApiResultCode.FAILURE, ""));
        }
        if (StringUtils.isEmpty(outRequestNo)) {
            logger.error("YsRefundServiceImpl --------------outRequestNo" + outRequestNo);
            return String.valueOf(ApiResult.failure(ApiResultCode.FAILURE, ""));
        }
        //业务参数（参数名biz_content,值为一个json格式对象，下面列表描述json对象的值）：
        Map<String, Object> businessMap = new HashMap<>();
        businessMap.put("biz_content", JSON.toJSONString(paraMap));
        //公共参数
        Map<String, String> commonMap = new HashMap<>();
        commonMap.put("method", "ysepay.online.trade.refund.query");
        commonMap.put("partner_id", ysPayDTO.getPARTNER_ID());
        commonMap.put("timestamp", DateFormatHelper.getNowTimeStr());
        commonMap.put("charset", ysPayDTO.getDEFAULT_CHARSET());
        commonMap.put("sign_type", ysPayDTO.getSIGN_ALGORITHM());
        commonMap.put("version", ysPayDTO.getVERSION());
        commonMap.put("biz_content", JSON.toJSONString(businessMap));
        Map<String, Object> map = null;
        //获取签名认证并校验签名信息
        try {
            Map<String, String> sParaMap = ysBuildRequestParaService.buildRequestPara(commonMap);
            String returns = Https.httpsSend(ysPayDTO.getYSEPAY_GATEWAY_URL_DSF(), sParaMap);
            logger.error("银盛返回值"+resultMap);
            resultMap = (Map) JSON.parse(returns);
            Object obj = resultMap.get("ysepay_online_trade_refund_query_response");
            boolean verifyResult = false;
            if(obj != null){
                //Map<String, Object> ysepay_online_trade_refund_query_response = (Map) JSON.parseObject(obj.toString());
                int yscount = returns.toString().indexOf("ysepay_online_trade_refund_query_response");
                str = returns.substring(yscount);
                str = str.replace("ysepay_online_trade_refund_query_response", "");
                str = str.substring(2, str.length() - 1);
                verifyResult = ysVerifyJsonSignService.verifyJsonSign(resultMap.get("sign").toString(), str, "utf-8");
                logger.info("YsRefundServiceImpl -------------------ysRefundQuery驗簽"+verifyResult);
                logger.info("YsRefundServiceImpl -------------------ysRefundQuery方法回执"+str);
                return str;
            }
        } catch (IOException e) {
            logger.error("YsRefundServiceImpl------------------------ysRefundQuery" +e.getMessage());
            e.printStackTrace();
        } catch (IllegalAccessException e1) {
            logger.error("YsRefundServiceImpl------------------------ysRefundQuery" +e1.getMessage());
            e1.printStackTrace();
        } finally {
            return str;
        }
    }


    //校验分账退款参数
    public Boolean verifyRoutingRefund(Map<String, Object> paraMap) {
        if (paraMap.isEmpty()) {
            logger.info("请求参数为空");
            return false;

        }else {
            String shopdate = paraMap.get("shopdate").toString();
            String refundAmount =  paraMap.get("refund_amount").toString();
            String refundReason =  paraMap.get("refund_reason").toString();
            String outRequestNo =  paraMap.get("out_request_no").toString();
            String orderDivList = paraMap.get("order_div_list").toString();
            String refund_split_info = paraMap.get("refund_split_info").toString();


            if (StringUtils.isEmpty(shopdate)) {
                logger.error("YsRefundServiceImpl-->verifyRoutingRefund params 商户日期为" + shopdate);
                return false;
            }
            if (StringUtils.isEmpty(refundAmount)) {
                logger.error("YsRefundServiceImpl-->verifyRoutingRefund params 退款金额为" + refundAmount);
                return false;
            }
            if (StringUtils.isEmpty(refundReason)) {
                logger.error("YsRefundServiceImpl-->verifyRoutingRefund params 退款说明为" + refundReason);
                return false;
            }
            if (StringUtils.isEmpty(outRequestNo)) {
                logger.info("YsRefundServiceImpl-->verifyRoutingRefund params 退款请求标示为" + outRequestNo);
                return false;
            }
            if (StringUtils.isEmpty(orderDivList)) {
                logger.info("YsRefundServiceImpl-->verifyRoutingRefund params order_div_list为" + orderDivList);
                return false;
            }
            if (StringUtils.isEmpty(refund_split_info)) {
                logger.info("YsRefundServiceImpl-->verifyRoutingRefund params order_div_list为" + orderDivList);
                return false;
            }
        }
        return true;
    }

    //请求参数入库并拼接业务参数
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveParam(Map<String, Object> paraMap) {

        String outTradeNo = (String) paraMap.get("out_trade_no");
        String shopdate = (String) paraMap.get("shopdate");
        String tradeNo = (String) paraMap.get("trade_no");
        //需要退款金額
        YsRefundRequestparamDO requestParamDO = new YsRefundRequestparamDO();
        String refundAmount = (String) paraMap.get("refund_amount");
        String refundReason = (String) paraMap.get("refund_reason");
        String outRequestNo = (String) paraMap.get("out_request_no");
        List order_div_list = (List) paraMap.get("order_div_list");
        List refund_split_info = (List) paraMap.get("refund_split_info");

        requestParamDO.setRefundType(RefundConstants.ROUTING_REFUND);
        requestParamDO.setOutTradeNo(outTradeNo);
        requestParamDO.setShopdate(shopdate);
        requestParamDO.setTradeNo(tradeNo);
        requestParamDO.setOrderDivList(order_div_list.toString());
        requestParamDO.setRefundSplitInfo(refund_split_info.toString());
        requestParamDO.setRefundAmount(new BigDecimal(refundAmount));
        requestParamDO.setRefundReason(refundReason);
        requestParamDO.setIsDelete(RefundConstants.COMMON_FLAG_UNDEL);
        requestParamDO.setOutRequestNo(outRequestNo);
        requestParamDO.setGmtCreate(new Date());
        int sum = ysRefundDao.save(requestParamDO);
        if (sum < 0) {
            return false;
        }
        return true;
    }

    //拼接业务参数并校验签名验证
    public Map<String, Object> routingJointVerifyParam(Map<String, Object> paraMap) throws Exception {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        YsPayDTO ysPayDTO = ysBusinessPramService.ysBusinessPram();
        Map<String, String> commonMap = new HashMap<>();
        //Map<String, Object> businessMap = new HashMap<>();
        //businessMap.put("biz_content", JSON.toJSONString(paraMap));
        //公共参数

        commonMap.put("method", "ysepay.online.trade.refund.split");
        commonMap.put("partner_id", ysPayDTO.getPARTNER_ID());
        commonMap.put("timestamp", DateFormatHelper.getNowTimeStr());
        commonMap.put("charset", ysPayDTO.getDEFAULT_CHARSET());
        commonMap.put("sign_type", ysPayDTO.getSIGN_ALGORITHM());
        commonMap.put("version", ysPayDTO.getVERSION());
        commonMap.put("biz_content", JSON.toJSONString(paraMap));
            Map<String, String> sParaMap = ysBuildRequestParaService.buildRequestPara(commonMap);
            String returns = Https.httpsSend(ysPayDTO.getYSEPAY_GATEWAY_URL(), sParaMap);
            logger.error("银盛返回值"+resultMap);
            resultMap = (Map) JSON.parse(returns);
            Object obj = resultMap.get("ysepay_online_trade_refund_split_response");
            boolean verifyResult = false;
            if(obj != null){
                //Map<String, Object> ysepay_online_trade_refund_split_response = (Map) JSON.parseObject(obj.toString());
                int yscount = returns.toString().indexOf("ysepay_online_trade_refund_split_response");
                String str = returns.substring(yscount);
                str = str.replace("ysepay_online_trade_refund_split_response", "");
                str = str.substring(2, str.length() - 1);
                verifyResult = ysVerifyJsonSignService.verifyJsonSign(resultMap.get("sign").toString(), str, "utf-8");
                //ysepay_online_trade_refund_split_response.put("sign", resultMap.get("sign"));
                //resultMap.putAll(ysepay_online_trade_refund_split_response);
                logger.info("YsRefundServiceImpl -------------------routingJointVerifyParam"+"校验是否成功"+verifyResult+resultMap);
                Map<String, Object> map = JSONUtils.jsonToMap(str);
                return map;
            }
        return null;
    }


}
